﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using DevExpress.XtraEditors;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace BuildHelper.Work.Tools.Forms
{
    public partial class CodeReview : XtraForm
    {
        public CodeReview()
        {
            InitializeComponent();
        }
        IntPtr codeReview;

        private void CodeReview_Load(object sender, EventArgs e)
        {
            this.textEdit1.Focus();
            this.textEdit1.SelectAll();
            Process[] sd = Process.GetProcessesByName("SoftDev");
            if (sd != null && sd.Length == 1)
            {
                Process softDev = sd[0];
                codeReview = GetCodeReview(softDev);

                if (codeReview != IntPtr.Zero)
                {
                    IntPtr grid = GlobalTools.TortoiseTools.FindWindowEx(codeReview, IntPtr.Zero, "MFCCmnGrid", null);
                    if (grid != null)
                    {
                        IntPtr ToolbarWindow32 = GlobalTools.TortoiseTools.FindWindowEx(grid, IntPtr.Zero, "ToolbarWindow32", null);
                       
                        System.Windows.Automation.AutomationElement elGrid = System.Windows.Automation.AutomationElement.FromHandle(grid);
                        if (elGrid != null)
                        {
                            object obj;
                            elGrid.TryGetCurrentPattern(elGrid.GetSupportedPatterns()[0], out obj);
                        }
                        //int count = textEdit1.EditValue.AsInt();
                        //for (int i = 0; i < count; i++)
                        //{
                        //    User32.PostMessage(grid, new IntPtr(0x0007), IntPtr.Zero, IntPtr.Zero);

                        //    User32.PostMessage(grid, new IntPtr(0x0100), new IntPtr(0x0D), new IntPtr(0x001C0001));
                        //    User32.PostMessage(grid, new IntPtr(0x0101), new IntPtr(0x0D), new IntPtr(0x001C0001));

                        //    User32.PostMessage(grid, new IntPtr(0x0100), new IntPtr(0x28), new IntPtr(0x00500001));
                        //    User32.PostMessage(grid, new IntPtr(0x0101), new IntPtr(0x28), new IntPtr(0x00500001));
                        //}
                    }
                }
            }
        }
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool EnumWindows(EnumThreadDelegate callback, IntPtr extraData);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);

        private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

        private IntPtr GetCodeReview(Process softDev)
        {
            IntPtr res = IntPtr.Zero;
            EnumWindows( (hwnd, lParam) =>
            {
                int i = 0;
                GetWindowThreadProcessId(hwnd, out i);
                if (i == softDev.Id)
                {
                    if (Win32.GetWindowText(hwnd) == "Code Review")
                    {
                        res = hwnd;
                        return false;
                    }
                }
                return true;
            },
            IntPtr.Zero);
            return res;
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            isExit = true;
            base.OnFormClosing(e);
        }
        private void btnStart_Click(object sender, EventArgs e)
        {
            Process[] sd = Process.GetProcessesByName("SoftDev");
            if (sd != null && sd.Length == 1)
            {
                Process softDev = sd[0];
                codeReview = GetCodeReview(softDev);

                if (codeReview != IntPtr.Zero)
                {
                    IntPtr grid = GlobalTools.TortoiseTools.FindWindowEx(codeReview, IntPtr.Zero, "MFCCmnGrid", null);
                    if (grid != null)
                    {
                        int count = textEdit1.EditValue.AsInt();
                        progressBarControl1.Properties.Maximum = count;
                        progressBarControl1.Position = 0;
                        this.ShowDxInfoDialog("Upewnij się, że zaznaczony jest pierwszy wiersz.");

                        Task t = Task.Factory.StartNew(CheckProc);
                        try
                        {
                            for (int i = 0; i < count; i++)
                            {
                                User32.PostMessage(grid, new IntPtr(0x0007), IntPtr.Zero, IntPtr.Zero);

                                User32.PostMessage(grid, new IntPtr(0x0100), new IntPtr(0x0D), new IntPtr(0x001C0001));
                                User32.PostMessage(grid, new IntPtr(0x0101), new IntPtr(0x0D), new IntPtr(0x001C0001));

                                User32.PostMessage(grid, new IntPtr(0x0100), new IntPtr(0x28), new IntPtr(0x00500001));
                                User32.PostMessage(grid, new IntPtr(0x0101), new IntPtr(0x28), new IntPtr(0x00500001));
                            }
                        }
                        catch (Exception ex)
                        {
                            this.ShowDxErrorDialog("Błąd podczas przeprowadzania CodeReview");
                            ex.Log();
                        }
                    }
                    else
                    {
                        this.ShowDxInfoDialog("Brak okna Code Review");
                    }
                }
                else
                {
                    this.ShowDxInfoDialog("Brak okna Code Review");
                }
            }
            else
            {
                this.ShowDxInfoDialog("Nie można zidentyfikować SoftDev'a");
            }
        }
        bool isExit = false;

        private void CheckProc()
        {
            Process[] sd = Process.GetProcessesByName("SoftDev");
            if (sd != null && sd.Length == 1)
            {
                Process softDev = sd[0];
                while (true)
                {
                    try
                    {
                        if (isExit || Program.IsExit)
                            break;
                        var l = softDev.GetChildProceses();
                        int ct = 0;
                        foreach (var p in l)
                        {
                            try
                            {
                                if (!p.HasExited && p.ProcessName.Contains("WinMerge"))
                                    ct++;
                            }
                            catch { }
                        }
                        if (ct > 0)
                        {
                            progressBarControl1.Invoke(new Action<int>((i) => { progressBarControl1.Position += i; }), ct);
                            foreach (var p in l)
                            {
                                try
                                {
                                    if (!p.HasExited && p.ProcessName.Contains("WinMerge"))
                                    { p.Kill(); p.Dispose(); }
                                }
                                catch { }
                            }
                        } 
                        if (progressBarControl1.Position == progressBarControl1.Properties.Maximum)
                        {
                            l = softDev.GetChildProceses();
                            foreach (var p in l)
                            {
                                try
                                {
                                    if (!p.HasExited && (p.ProcessName.Contains("WinMerge") || p.ProcessName.Contains("SVNCommand")))
                                    { p.Kill(); p.Dispose(); }
                                }
                                catch { }
                            }
                            CloseMe();
                        }
                        System.Threading.Thread.Sleep(60);
                    }
                    catch(Exception ex)
                    {
                        ex.Log();
                        break;
                    }
                }
            }
        }

        private void CloseMe()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(CloseMe));
                return;
            }
            else
            {
                if (ceCloseWinMerge.Checked)
                {
                    Close();
                }
            }
        }
        private void simpleButton1_Click(object sender, EventArgs e)
        {
            Process[] sd = Process.GetProcessesByName("SoftDev");
            if (sd != null && sd.Length == 1)
            {
                Process softDev = sd[0];
                var l = softDev.GetChildProceses();
                foreach (var p in l)
                {
                    try
                    {
                        if (p.ProcessName.Contains("WinMerge") || p.ProcessName.Contains("SVNCommand"))
                        { p.Kill(); p.Dispose(); }
                    }
                    catch { }
                }
            }
        }
    }
}
